<template>
    <div class="edit-data">
        <el-dialog v-if="visible" :visible.sync="visible" :close-on-click-modal="false" :close-on-press-escape="false" width="70%" modal-append-to-body :before-close="handleClose" class="review-editchart-dialog">
            <div class="edit-tab-title">
                <div v-for="item in dataType" :key="item.value" class="sub-title" @click="changeType(item.value)" :class="{ active: type == item.value }">
                    {{ item.label }}
                </div>
            </div>
            <div class="edit-content" v-if="type === 'static' && visible === true" key="static">
                <div class="left-content">
                    <Upload :value="staticValue" :mode="mode" @success="uploadFinish" />
                    <Download :value="staticValue" />
                </div>
                <div class="table-content">
                    <EditData ref="editData" editable="0" :value="type === 'static' ? staticValue: dynamicValue" :headList="headList" :editCallback="editCallback" />
                </div>
                <div class="thead-content">
                    <EditList :headList="headList" :mode="mode" :field="field" :draggable="draggable" ref="editList" />
                </div>
            </div>
            <div class="edit-content" v-if="type === 'dynamic' && visible === true" key="dynamic">
                <div class="left-content">
                    <div class="edit-table-tree">
                        <el-tree :data="treeList" default-expand-all ref="tree" highlight-current :expand-on-click-node="false" :props="defaultProps" @node-click="setDynamicTableData" class="review-edit-tree">
                            <span class="custom-tree-node" :class="{ 'optional-node': data.available }" slot-scope="{ node, data }">
                                <span>{{ node.label }}</span>
                            </span>
                        </el-tree>
                    </div>
                </div>
                <div class="table-content">
                    <EditData ref="editData" editable="1" :value="type === 'static' ? staticValue: dynamicValue" :headList="headList" :editCallback="editCallback" />
                </div>
                <div class="thead-content">
                    <div class="editchart-api main-panel-content-wrap">
                        <div class="main-base-row-item-grid">
                            <div class="main-mas-input-simple main-mas-input-simple-input">
                                <div class="mas-basic-layout">
                                    <input @keyup.enter="getRequestData" v-model="url" placeholder="请输入url" class="mas-basis-input mas-basis-input2" />
                                </div>
                            </div>
                        </div>
                        <div class="main-base-row-item-grid main-row-grid-2">
                            <div class="main-text-tran-50">自动更新请求：</div>
                            <div class="main-mas-input-simple main-mas-input-simple-input">
                                <div class="mas-basic-layout">
                                    <select v-model="interval" class="main-mas-basis-select">
                                        <option :value="item.value" v-for="(item, index) in refreshTime" :key="index">
                                            {{ item.label }}</option>
                                    </select>
                                </div>
                            </div>
                        </div>
                        <div class="main-base-row-item-grid main-row-grid-2">
                            <div class="main-mas-input-simple main-mas-input-simple-input">
                                <div class="mas-basic-layout">
                                    <select v-model="method" class="main-mas-basis-select" placeholder="请求类型">
                                        <option :value="item.value" v-for="(item, index) in requestMethod" :key="index">
                                            {{ item.label }}</option>
                                    </select>
                                </div>
                            </div>
                            <div class="edit-data-btn" @click="getRequestData">确&nbsp;定</div>
                        </div>
                    </div>
                    <EditList :headList="headList" :mode="mode" :field="field" :draggable="draggable" ref="editList" />
                </div>
            </div>
            <div slot="footer" class="dialog-footer">
                <div class="main-base-row-item-grid dialog-footer-row">
                    <div class="edit-data-btn-cancel" @click="closeDialog">取&nbsp;消</div>
                    <div class="edit-data-btn" @click="save">确&nbsp;定</div>
                </div>
            </div>
        </el-dialog>
    </div>
</template>

<script>
import message from '@/js/util/message.js';
import JQuery from 'jquery';
import status from '@/js/main/status.js';
import editor from '@/js/main/editor.js';

export default {
    name: 'editData',
    components: {
        EditData: () => import('@/view/main/editor/EditData.vue'),
        EditList: () => import('@/view/main/editor/EditList.vue'),
        Upload: () => import('@/view/main/editor/Upload.vue'),
        Download: () => import('@/view/main/editor/Download.vue')
    },
    data() {
        return {
            dataType: [
                {
                    value: 'static',
                    label: '静态数据'
                },
                {
                    value: 'dynamic',
                    label: '接口接入'
                }
            ],
            requestMethod: [
                {
                    value: '0',
                    label: 'GET'
                },
                {
                    value: '1',
                    label: 'POST'
                }
            ],
            treeList: [],
            defaultProps: {
                children: 'children',
                label: 'label'
            },
            refreshTime: [
                {
                    value: -1,
                    label: '不自动刷新'
                },
                {
                    value: 5 * 1000,
                    label: '5秒'
                },
                {
                    value: 60 * 1000,
                    label: '1分钟'
                },
                {
                    value: 5 * 60 * 1000,
                    label: '5分钟'
                },
                {
                    value: 10 * 60 * 1000,
                    label: '10分钟'
                },
                {
                    value: 15 * 60 * 1000,
                    label: '15分钟'
                },
                {
                    value: 60 * 60 * 1000,
                    label: '1小时'
                },
                {
                    value: 2 * 60 * 60 * 1000,
                    label: '2小时'
                }
            ],
            type: 'static',
            dynamicValue: [], // 动态数据
            staticValue: [], // 静态数据
            objectKey: [],
            availableList: [],
            headList: [],
            requestData: {},
            url: '', // http://localhost:3000/mock.json
            method: '0',
            interval: -1,
            mode: '0', // 0 默认 可新增右侧，1 不可新增固定，2 table独有
            dataReturnType: 'Array',
            field: [],
            complete: null,
            visible: false,
            draggable: false
        };
    },
    mounted() {
        editor.initialize(this);
    },
    methods: {
        open() {
            if (this.type === 'dynamic') {
                this.getRequestData();
            } else if (this.type === 'static') {
                if (this.staticValue.length) {
                    this.headList = this.staticValue[0];
                }
            }
            status.setEditTable(true);
            this.visible = true;
        },
        close() {
            status.setEditTable(false);
            this.visible = false;
            Object.assign(this.$data, this.$options.data());
        },
        setDraggable(draggable) {
            this.draggable = draggable || false;
        },
        setUrl(url) {
            this.url = url || '';
        },
        setType(type) {
            this.type = type || 'static';
        },
        setMethod(method) {
            this.method = method || '0';
        },
        setValue(staticValue) {
            this.staticValue = staticValue || [];
        },
        setInterval(interval) {
            this.interval = interval || -1;
        },
        setMode(mode) {
            this.mode = mode || '0';
        },
        setDataRetrunType(dataReturnType) {
            this.dataReturnType = dataReturnType || 'Array';
        },
        setField(field) {
            this.field = field || [];
        },
        setComplete(complete) {
            this.complete = complete || function() {};
        },
        uploadFinish(data) {
            this.$refs.editData.setTableData(data);
            this.headList = data[0];
        },
        changeType(value) {
            this.type = value;
            if (value === 'static') {
                this.headList = this.staticValue[0];
            } else {
                if (this.dynamicValue.length) {
                    this.headList = this.dynamicValue[0];
                }
            }
        },
        save() {
            let completeEditMap = {
                type: this.type,
                url: this.url,
                objectKey: this.objectKey,
                interval: this.interval,
                method: this.method,
                field: this.field
            };
            if (this.$refs.editData && this.$refs.editData.getTableData) {
                let data = this.$refs.editData.getTableData();
                completeEditMap.data = data;
            }
            this.complete(completeEditMap);
        },
        editCallback() {
            if (this.$refs.editData && this.$refs.editData.getTableData) {
                let data = this.$refs.editData.getTableData();
                if (data.length) {
                    this.headList = data[0];
                }
            }
        },
        getRequestData() {
            this.availableList = [];
            this.dynamicValue = [];
            this.objectKey = [];
            this.treeList = [];
            this.requestData = {};
            let method = 'POST';
            if (this.method === '0') {
                method = 'GET';
            } else {
                method = 'POST';
            }
            if (this.url) {
                let data = JQuery.ajax({
                    url: this.url,
                    async: false,
                    type: method,
                    data: {}
                }).responseJSON;
                this.requestData = { 数据对象: data };
                this.treeList = this.getTree(this.requestData);
                if (this.availableList.length) {
                    this.dynamicValue = this.transferData(this.availableList[0]);
                    this.headList = this.dynamicValue[0];
                    this.objectKey = this.availableList[0].key;
                }
                if (this.$refs.editData && this.$refs.editData.setTableData) {
                    this.$refs.editData.setTableData(this.dynamicValue);
                }
            } else {
                message.message('请输入有效的url地址', 'warning');
            }
        },
        getTree(target, keys = []) {
            if (typeof target == 'object') {
                let ls = [];
                for (let key in target) {
                    keys.push(key);
                    let type = '';
                    let item = {};
                    item.label = key;
                    item.key = [...keys];
                    if (Object.prototype.toString.call(target[key]) === '[object Object]') {
                        type = 'object';
                    } else if (Object.prototype.toString.call(target[key]) === '[object Array]') {
                        type = 'array';
                    } else {
                        type = 'string';
                    }
                    item.type = type;
                    item.children = [];
                    if (typeof target[key] == 'object') {
                        let children = this.getTree(target[key], keys);
                        item.children = [...item.children, ...children];
                    }
                    item.available = this.available(item);
                    if (item.available) {
                        this.availableList.push(item);
                    }
                    ls.push(item);
                    keys.splice(keys.length - 1, 1);
                }
                return ls;
            }
            return [];
        },
        available(item) {
            let is = true;
            if (this.dataReturnType === 'Object') {
                is = (is && item.type === 'array') || (is && item.type === 'object');
            } else {
                is = is && item.type === 'array';
            }
            if (is) {
                let children0 = item.children;
                if (children0.length) {
                    for (let a = 0; a < children0.length; a++) {
                        let node0 = children0[a];
                        if (node0.type === 'string' && this.dataReturnType === 'Object') {
                            break;
                        }
                        is = is && (node0.type === 'array' || node0.type === 'object');
                        let children1 = node0.children;
                        if (children1.length && is) {
                            for (let b = 0; b < children1.length; b++) {
                                let node1 = children1[b];
                                is = is && node1.type === 'string';
                                if (!is) {
                                    break;
                                }
                            }
                        } else {
                            is = false;
                        }
                        if (!is) {
                            break;
                        }
                    }
                } else {
                    is = false;
                }
            }
            return is;
        },
        closeDialog() {
            Object.assign(this.$data, this.$options.data());
            this.close();
        },
        handleClose(done) {
            Object.assign(this.$data, this.$options.data());
            done();
            this.close();
        },
        transferData(data) {
            let dynamicValue = [];
            if (data && data.available) {
                let list = this.getData(this.requestData, data.key);
                if (Object.prototype.toString.call(list) === '[object Object]') {
                    list = [list]
                }
                let headerObject = {};
                let headList = [];
                for (let a in list) {
                    for (let b in list[a]) {
                        if (headerObject[b] != true) {
                            headList.push(b);
                            headerObject[b] = true;
                        }
                    }
                }
                dynamicValue.push(headList);
                for (let a = 0; a < list.length; a++) {
                    dynamicValue.push([]);
                    for (let i = 0; i < headList.length; i++) {
                        let value = list[a][headList[i]];
                        if (value == null || value == undefined) {
                            value = '';
                        }
                        dynamicValue[a + 1].push(value);
                    }
                }
            }
            return dynamicValue;
        },
        setDynamicTableData(data) {
            if (data.available) {
                this.dynamicValue = this.transferData(data);
                this.headList = this.dynamicValue[0];
                this.objectKey = this.availableList[0].key;
                if (this.$refs.editData && this.$refs.editData.setTableData) {
                    this.$refs.editData.setTableData(this.dynamicValue);
                }
            } else {
                message.message('数据不符合要求！！', 'warning');
            }
        },
        getData(data, array) {
            let value = data;
            for (let index = 0; index < array.length; index++) {
                value = value[array[index]];
            }
            if (value == data) {
                return null;
            } else {
                return value;
            }
        }
    }
};
</script>
<style lang="scss" scoped>
.edit-data {
    .editchart-api {
        margin: 0 20px 20px;
    }
}

.edit-data-btn {
    height: 30px;
    line-height: 30px;
    background: #3664ece6;
    color: $FontWhite;
    text-align: center;
    border-radius: 5px;
    cursor: pointer;
    &:hover {
        background: #3664ecff;
    }
}

.edit-data-btn-cancel {
    height: 30px;
    line-height: 30px;
    background: #ffffff0f;
    color: $FontWhite;
    text-align: center;
    border-radius: 5px;
    cursor: pointer;
    &:hover {
        background: #ffffff33;
    }
}

.review-editchart-dialog {
    ::v-deep.el-dialog {
        display: flex;
        flex-direction: column;
        height: 70%;
        background: #212121;
    }
    ::v-deep.el-dialog .el-dialog__body {
        flex: 1;
        padding: 0;
        overflow: hidden;
    }
    ::v-deep.el-dialog__header {
        padding: 5px 10px;
    }
    .dialog-footer {
        float: right;
        width: 180px;
    }
    .dialog-footer-row {
        grid-template-columns: repeat(2, 50%);
    }
}

.edit-table-tree {
    position: relative;
    height: 100%;
    overflow: auto;
    .el-tree {
        color: #ffffffc4;
    }
}

.review-edit-tree {
    background: transparent;
    .optional-node {
        color: #67c23a;
    }

    .el-tree-node__content > .el-tree-node__expand-icon {
        line-height: 0;
    }
    .el-tree-node:focus > .el-tree-node__content {
        background-color: transparent !important;
    }
    .expanded,
    .el-tree-node__expand-icon,
    .el-icon-caret-right {
        line-height: 0;
    }
    .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
        background: transparent;
    }
    .el-tree-node__content {
        align-items: flex-start;
    }
    ::v-deep.el-tree-node__content:active {
        background: #ffffff4d;
    }
}
.edit-tab-title {
    height: 40px;
    line-height: 40px;
    border-bottom: 1px solid #ffffff0f;
    margin: 0px 20px 10px;
    display: flex;
    .sub-title {
        margin-right: 20px;
        padding: 0 15px;
        height: 40px;
        cursor: pointer;
    }
    .active {
        border-bottom: #5bc4d6 1px solid;
        color: #ffffff;
    }
}
.edit-content {
    margin: 0 20px;
    display: flex;
    height: calc(100% - 50px);
}
.left-content {
    width: 250px;
    padding: 0 20px;
    height: 100%;
}
.table-content {
    overflow: auto;
    width: calc(100% - 550px);
}
.table-content-table {
    width: calc(100% - 250px);
}
.thead-content {
    width: 300px;
    overflow-y: auto;
}
</style>